// tslint:disable:max-line-length
import { ElementPropertyConfig, BeforeOpenModalResult, PropertyEntity, KeyMap } from '@farris/ide-property-panel';
import { EditorTypes } from '@farris/ui-datagrid-editors';
import { DgControl } from '../../../../../../utils/dg-control';
import { ItemCollectionEditorComponent, ItemCollectionConverter, MappingConverter, SelectMappingComponent } from '@farris/designer-devkit';
// import { SelectHelpMetadataComponent } from '../../../../../input/lookup-edit/property/editors/select-help-metadata/select-help-metadata.component';
// import { SelectHelpConverter } from '../../../../../input/lookup-edit/property/editors/select-help-metadata/select-help-converter';
// import { SelectHelpTextFieldComponent } from '../../../../../input/lookup-edit/property/editors/select-help-text-field/select-help-text-field.component';
import { EventEditorService, FormSchemaEntityField, FormSchemaEntityFieldTypeName, WebCmdService, FormBasicService, DomService, FormSchemaEntityFieldType$Type, DesignViewModelService, SchemaService } from '@farris/designer-services';
import { CodeEditorComponent, ImportCmpComponent, ImportCmpConverter } from '@farris/designer-devkit';
import { SelectHelpClearFieldsEditorComponent } from './select-help-clear-fields/select-help-clear-fields.component';
import { InputgroupFormMappingEditorComponent } from './inputgroup-form-mapping-editor/inputgroup-form-mapping-editor';
import { QuerySchemaFieldCreator } from './query-data/field-control-data';
import { QuerySchemaFieldTypeEnums } from './query-data/field-control-types';
import { DATE_FORMATS } from '../../../../../input/date-box/property/date-format';
// import { SelectHelpDisplayFieldsComponent } from '../../../../../input/lookup-edit/property/editors/select-help-display-fields/select-help-display-fields.component';
import { Injectable } from '@angular/core';
import { EventsEditorFuncUtils } from '../../../../../../utils/events-editor-func';
import { FormPropertyChangeObject } from '../../../../../../entity/property-change-entity';
import { MessagerService } from '@farris/ui-messager';
import { Subject } from 'rxjs';

/**
 * 筛选方案相关特性
 */
@Injectable()
export class SchemeFeatureService {

    /** 字段配置 */
    fieldConfigs: any[];

    /** 属性配置 */
    propertyConfig: ElementPropertyConfig[];

    /** 触发关闭编辑器，用于在交互面板中跳转到代码视图之前将编辑器弹窗关闭 */
    triggerSaveAndCloseEditor = new Subject<any>();

    constructor(
        private domService: DomService,
        private webCmdService: WebCmdService,
        private formBasicService: FormBasicService,
        private eventEditorService: EventEditorService,
        private msgService: MessagerService,
        private schemaService: SchemaService,
        private dgVMService: DesignViewModelService) { }

    /**
     * 筛选方案支持的编辑器类型
     */
    allowedFieldType = [
        FormSchemaEntityFieldTypeName.String,
        FormSchemaEntityFieldTypeName.Number,
        FormSchemaEntityFieldTypeName.BigNumber,
        FormSchemaEntityFieldTypeName.Date,
        FormSchemaEntityFieldTypeName.DateTime,
        FormSchemaEntityFieldTypeName.Boolean,
        FormSchemaEntityFieldTypeName.Enum
    ];

    enumDataConfig;


    getPropertyConfig(schemaField: FormSchemaEntityField, fieldObject: any, viewModelId: string, fieldConfigs: any[]): ElementPropertyConfig[] {
        if (!fieldObject) {
            return [];
        }
        this.fieldConfigs = fieldConfigs || [];
        const self = this;
        if (fieldObject.control) {
            fieldObject.control.id = fieldObject.id;
        }
        this.enumDataConfig = this.getEnumDataConfig(fieldObject.control, schemaField);
        this.propertyConfig = [];
        let openModalPropConfigs;
        if (schemaField.type.name === FormSchemaEntityFieldTypeName.String) {
            // 智能输入框----弹出表单框属性
            openModalPropConfigs = this.getOpenModalPropConfigs(fieldObject, viewModelId);
        }
        const properties = this.getUsualPropertyEntities(schemaField, fieldObject, viewModelId, fieldConfigs);
        const usualConfig: ElementPropertyConfig = {
            categoryId: 'usual',
            categoryName: '常规',
            hideTitle: true,
            properties,
            setPropertyRelates(changeObject: any, propertyData: any, parameters: any) {
                switch (changeObject.propertyID) {
                    case 'controltype': {
                        // 切换类型：重新设置control节点，以便清除与当前类型无关的属性值;保留className属性
                        const oldControl = propertyData.control;
                        propertyData.control = QuerySchemaFieldCreator.getControlDataByType(
                            changeObject.propertyValue, schemaField);
                        Object.assign(propertyData.control, {
                            className: oldControl.className,
                            require: oldControl.require
                        });
                        self.setOpenModalConfigDisplay(propertyData, openModalPropConfigs);
                        self.enumDataConfig = self.getEnumDataConfig(propertyData.control, schemaField);

                        // 重置属性分类
                        const newProps = self.getUsualPropertyEntities(schemaField, propertyData, viewModelId, fieldConfigs);
                        Object.assign(this.properties, newProps);

                        // 重置帮助快捷选择分类
                        const newHelpQuickSelectConfig = self.getHelpQuickSelectPropConfig(propertyData, viewModelId);
                        const currentHelpQuickSelectConfig = self.propertyConfig.find(cat => cat.categoryId === 'helpQuickSelect');
                        Object.assign(currentHelpQuickSelectConfig, newHelpQuickSelectConfig);

                        // 重置事件分类
                        const newEventConfig = self.getEventPropertyConfig(propertyData, viewModelId);
                        const currentEventConfig = self.propertyConfig.find(cat => cat.categoryId === 'eventsEditor');
                        Object.assign(currentEventConfig, newEventConfig);

                        break;
                    }
                    case 'helpId': {
                        // 选择帮助元数据返回的是DataSource，需要拆分出uri和idField
                        if (!changeObject.propertyValue) {
                            Object.assign(propertyData.control,
                                {
                                    helpId: '', uri: '', idField: '', valueField: '', textField: '', displayType: '',
                                    enableExtendLoadMethod: true, enableFullTree: false, loadTreeDataType: 'default',
                                    multiSelect: false, expandLevel: -1
                                });
                            if (propertyData.control.controltype === 'help') {
                                propertyData.control.enableCascade = false;
                                propertyData.control.displayFields = '';
                            }
                        } else {
                            const { uri, idField } = changeObject.propertyValue;
                            propertyData.control.uri = uri;
                            propertyData.control.idField = idField;
                            Object.assign(propertyData.control, parameters);

                            propertyData.control.displayFields = '';

                            const controlProp = this.properties.find(p => p.propertyID === 'control');

                            controlProp.cascadeConfig.map(p => {
                                // 旧表单手动添加的displayType 大小写不一定，故转换为小写再对比
                                if (p.propertyID === 'enableFullTree' || p.propertyID === 'expandLevel') {
                                    p.visible = parameters.displayType.toLowerCase() === 'treelist' ||
                                        parameters.displayType.toLowerCase() === 'navtreelist';
                                }
                                if (p.propertyID === 'enableCascade') {
                                    p.visible = propertyData.control.controltype === 'help' && propertyData.control.multiSelect &&
                                        (parameters.displayType.toLowerCase() === 'treelist' ||
                                            parameters.displayType.toLowerCase() === 'navtreelist');
                                }
                                if (p.propertyID === 'cascadeStatus') {
                                    p.visible = propertyData.control.controltype === 'help' && propertyData.control.multiSelect &&
                                        (parameters.displayType.toLowerCase() === 'treelist' ||
                                            parameters.displayType.toLowerCase() === 'navtreelist') && propertyData.control.enableCascade;
                                }
                                if (p.propertyID === 'loadTreeDataType') {
                                    p.visible = parameters.displayType.toLowerCase() === 'treelist';
                                }
                                if (p.propertyID === 'enableExtendLoadMethod') {
                                    p.visible = true;
                                }
                                // 映射属性中配置帮助id
                                if (p.propertyID === 'mapFields') {
                                    p.editorParams.sourceMetadataId = parameters ? parameters.helpId : '';
                                }

                                // 分页属性
                                if (p.propertyID === 'pageList') {
                                    p.visible = propertyData.control.controltype === 'help' && parameters.displayType && parameters.displayType.toLowerCase() !== 'treelist';
                                }
                                if (p.propertyID === 'pageSize') {
                                    p.visible = propertyData.control.controltype === 'help' && parameters.displayType && parameters.displayType.toLowerCase() !== 'treelist';
                                    if (p.visible) {
                                        p.iterator = self.getPageSizeIterator(propertyData.control.pageList);
                                    }
                                }
                            });
                        }

                        // 重置帮助快捷选择分类
                        const newHelpQuickSelectConfig = self.getHelpQuickSelectPropConfig(propertyData, viewModelId);
                        const currentHelpQuickSelectConfig = self.propertyConfig.find(cat => cat.categoryId === 'helpQuickSelect');
                        Object.assign(currentHelpQuickSelectConfig, newHelpQuickSelectConfig);

                        break;
                    }
                    case 'multiSelect': {
                        const control = propertyData.control;
                        if (control.controltype === 'help' && control.displayType &&
                            (control.displayType.toLowerCase() === 'treelist' || control.displayType.toLowerCase() === 'navtreelist')) {
                            const controlProp = this.properties.find(p => p.propertyID === 'control');
                            const enableCascade = controlProp.cascadeConfig.find(p => p.propertyID === 'enableCascade');
                            enableCascade.visible = propertyData.control.multiSelect;

                            const cascadeStatus = controlProp.cascadeConfig.find(p => p.propertyID === 'cascadeStatus');
                            if (cascadeStatus) {
                                cascadeStatus.visible = propertyData.control.multiSelect && propertyData.control.enableCascade;
                            }

                        }
                        // 重置帮助快捷选择分类
                        if (control.controltype === 'help') {
                            const newHelpQuickSelectConfig = self.getHelpQuickSelectPropConfig(propertyData, viewModelId);
                            const currentHelpQuickSelectConfig = self.propertyConfig.find(cat => cat.categoryId === 'helpQuickSelect');
                            Object.assign(currentHelpQuickSelectConfig, newHelpQuickSelectConfig);
                        }
                        break;
                    }
                    case 'maxValue': {
                        const controlProp = this.properties.find(p => p.propertyID === 'control');
                        const minProp = controlProp.cascadeConfig.find(p => p.propertyID === 'minValue');
                        if (minProp) {
                            const newPropConfig = self.getMinDatePropConfig(fieldObject, viewModelId);
                            Object.assign(minProp, newPropConfig);
                        }
                        break;
                    }
                    case 'minValue': {
                        const controlProp = this.properties.find(p => p.propertyID === 'control');
                        const maxProp = controlProp.cascadeConfig.find(p => p.propertyID === 'maxValue');
                        if (maxProp) {
                            const newPropConfig = self.getMaxDatePropConfig(fieldObject, viewModelId);
                            Object.assign(maxProp, newPropConfig);
                        }
                        break;
                    }
                    case 'precision': {
                        const controlProp = this.properties.find(p => p.propertyID === 'control');
                        const minProp = controlProp.cascadeConfig.find(p => p.propertyID === 'minValue');
                        const maxProp = controlProp.cascadeConfig.find(p => p.propertyID === 'maxValue');

                        minProp.decimals = changeObject.propertyValue;
                        maxProp.decimals = changeObject.propertyValue;
                        break;
                    }
                    case 'usageMode': {
                        self.setOpenModalConfigDisplay(propertyData, openModalPropConfigs);
                        if (propertyData.control.modalConfig) {
                            propertyData.control.modalConfig.mapFields = '';
                            propertyData.control.modalConfig.modalCmp = '';
                            propertyData.control.modalConfig.component = '';
                            propertyData.control.modalConfig.formId = '';
                        }
                        break;
                    }
                    case 'pageList': {
                        changeObject.propertyValue = propertyData.control.pageList = self.checkPageList(changeObject.propertyValue);
                        const controlProp = this.properties.find(p => p.propertyID === 'control');
                        const pageSize = controlProp.cascadeConfig.find(p => p.propertyID === 'pageSize');

                        if (pageSize) {
                            pageSize.iterator = self.getPageSizeIterator(changeObject.propertyValue);
                        }
                        if (!changeObject.propertyValue.includes(propertyData.control.pageSize)) {
                            propertyData.control.pageSize = null;
                        }
                        break;
                    }
                    case 'enableCustomFormat': {
                        const controltype = propertyData.control.controltype;
                        const controlProp = this.properties.find(p => p.propertyID === 'control');
                        const format = controlProp.cascadeConfig.find(p => p.propertyID === 'format');
                        if (format) {
                            format.iterator = self.getDateFormatIteratror(controltype, changeObject.propertyValue, propertyData.control.returnFormat);
                        }
                        const formatKeys = format.iterator.map(i => i.key);
                        if (!formatKeys.includes(propertyData.control.format)) {
                            propertyData.control.format = formatKeys[0];
                        }

                        const returnFormat = controlProp.cascadeConfig.find(p => p.propertyID === 'returnFormat');
                        if (returnFormat) {
                            returnFormat.iterator = self.getDateReturnFormatIteratror(controltype, changeObject.propertyValue);
                        }

                        break;
                    }
                    case 'returnFormat': {
                        const controltype = propertyData.control.controltype;
                        const controlProp = this.properties.find(p => p.propertyID === 'control');

                        const enableCustomFormat = controlProp.cascadeConfig.find(p => p.propertyID === 'enableCustomFormat');
                        if (enableCustomFormat) {
                            enableCustomFormat.readonly = changeObject.propertyValue && !changeObject.propertyValue.includes('HH');
                        }
                        if (enableCustomFormat.readonly) {
                            propertyData.control.enableCustomFormat = enableCustomFormat.readonly;
                        }


                        const format = controlProp.cascadeConfig.find(p => p.propertyID === 'format');
                        if (format) {
                            format.iterator = self.getDateFormatIteratror(controltype, propertyData.control.enableCustomFormat, propertyData.control.returnFormat);
                        }
                        const formatKeys = format.iterator.map(i => i.key);
                        if (!formatKeys.includes(propertyData.control.format)) {
                            propertyData.control.format = formatKeys[0];
                        }
                        break;
                    }
                    case 'enumValues': {
                        if (self.enumDataConfig.dynamicMappingKeys && parameters) {
                            propertyData.control.idField = parameters.valueField;
                            propertyData.control.textField = parameters.nameField;
                        }
                        break;
                    }
                    case 'enableCascade': {
                        const controlProp = this.properties.find(p => p.propertyID === 'control');
                        const cascadeStatus = controlProp.cascadeConfig.find(p => p.propertyID === 'cascadeStatus');
                        if (cascadeStatus) {
                            cascadeStatus.visible = changeObject.propertyValue;
                        }
                    }
                }
            }
        };
        this.propertyConfig.push(usualConfig);
        if (openModalPropConfigs) {
            this.propertyConfig = this.propertyConfig.concat(openModalPropConfigs);
        }

        const helpQuickSelectConfig = this.getHelpQuickSelectPropConfig(fieldObject, viewModelId);
        if (helpQuickSelectConfig) {
            this.propertyConfig.push(helpQuickSelectConfig);
        }
        const eventConfig = this.getEventPropertyConfig(fieldObject, viewModelId);
        this.propertyConfig.push(eventConfig);

        return this.propertyConfig;
    }
    /**
     * 获取交互面板配置
     * @param propertyData 属性值
     */
    private getEventPropertyConfig(propertyData: any, viewModelId: string): ElementPropertyConfig {
        const self = this;
        const domService = this.domService;
        const webCmdService = this.webCmdService;
        const formBasicService = this.formBasicService;
        const eventEditorService = this.eventEditorService;
        let eventList = [];
        const controlData = propertyData.control;
        eventList = this.switchEvents(controlData, eventList);
        return {
            categoryId: 'eventsEditor',
            categoryName: '事件',
            hideTitle: true,
            properties: EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, controlData, viewModelId, eventList, this.switchEvents),
            tabId: 'commands',
            tabName: '交互',
            enableCascade: true,
            propertyData: controlData,
            parentPropertyID: 'control',
            setPropertyRelates(changeObject: FormPropertyChangeObject, data: any, parameters: any) {
                delete controlData[viewModelId];
                // 若需要跳转到代码视图，首先要求用户将当前弹出窗口关闭
                if (parameters.isAddControllerMethod) {
                    self.msgService.question('确定关闭当前编辑器并跳转到代码视图吗？', () => {
                        // 暂存控件信息，用于自动创建新方法的方法编号和名称
                        parameters.controlInfo = { type: propertyData.code, name: propertyData.name };

                        self.triggerSaveAndCloseEditor.next();
                        EventsEditorFuncUtils.saveRelatedParameters(eventEditorService, domService, webCmdService, controlData, viewModelId, parameters['events'], parameters);
                        this.properties = EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, controlData, viewModelId, parameters['events'], self.switchEvents);
                    });
                } else {
                    EventsEditorFuncUtils.saveRelatedParameters(eventEditorService, domService, webCmdService, controlData, viewModelId, parameters['events'], parameters);
                    this.properties = EventsEditorFuncUtils.formProperties(eventEditorService, formBasicService, domService, webCmdService, controlData, viewModelId, parameters['events'], self.switchEvents);
                }

            }
        };
    }
    /**
     * 处理动态事件属性
     * @param fieldObject 属性值
     * @param eventList 事件列表
     */
    private switchEvents(fieldObjectControl: any, eventList: { label: string, name: string }[]) {
        const controlType = fieldObjectControl.controltype;
        // 帮助相关事件
        if (controlType.includes('help')) {
            if (!eventList.find(e => e.label === 'preEventCmd')) {
                eventList.push(
                    {
                        label: 'preEventCmd',
                        name: '帮助前事件'
                    },
                    {
                        label: 'postEventCmd',
                        name: '帮助后事件'
                    }
                );
            }

            if (controlType === 'help') {
                if (!eventList.find(e => e.label === 'clear')) {
                    eventList.push(
                        {
                            label: 'clear',
                            name: '帮助清空事件'
                        }
                    );
                }
            }

        } else {
            eventList = eventList.filter(e => e.label !== 'preEventCmd' && e.label !== 'postEventCmd' && e.label !== 'clear');
        }

        // 智能输入框相关事件
        if (controlType === 'input-group') {
            if (!eventList.find(e => e.label === 'click')) {
                eventList.push(
                    {
                        label: 'click',
                        name: '点击事件'
                    }
                );
            }
        } else {
            eventList = eventList.filter(e => e.label !== 'click');
        }

        // 下拉选择事件
        if (controlType.includes('dropdown')) {
            if (!eventList.find(e => e.label === 'beforeShow')) {
                eventList.push(
                    {
                        label: 'beforeShow',
                        name: '面板显示前事件'
                    },
                    {
                        label: 'beforeHide',
                        name: '面板隐藏前事件'
                    }
                );
            }
        } else {
            eventList = eventList.filter(e => e.label !== 'beforeShow' && e.label !== 'beforeHide');
        }

        // 日期选择值变化事件
        if (controlType.includes('year') || controlType.includes('month') || controlType.includes('date')) {
            if (!eventList.find(e => e.label === 'valueChangedCmd')) {
                eventList.push(
                    {
                        label: 'valueChangedCmd',
                        name: '值变化事件'
                    }
                );
            }
        } else {
            eventList = eventList.filter(e => e.label !== 'valueChangedCmd');
        }

        return eventList;
    }

    private getPlaceHolder(controlType: string) {
        return [
            {
                propertyID: 'beginPlaceHolder',
                propertyName: '开始占位符文本',
                propertyType: 'string',
                visible: QuerySchemaFieldCreator.rangePlaceHolderControl.includes(controlType)
            },
            {
                propertyID: 'endPlaceHolder',
                propertyName: '结束占位符文本',
                propertyType: 'string',
                visible: QuerySchemaFieldCreator.rangePlaceHolderControl.includes(controlType)
            },
            {
                propertyID: 'placeHolder',
                propertyName: '占位符文本',
                propertyType: 'string',
                visible: !QuerySchemaFieldCreator.rangePlaceHolderControl.includes(controlType)
            }
        ];
    }

    private setOpenModalConfigDisplay(propertyData: any, openModalPropConfigs: ElementPropertyConfig[]) {
        if (!openModalPropConfigs || !propertyData.control) {
            return;
        }
        if (propertyData.control.controltype !== 'input-group') {
            openModalPropConfigs.forEach(config => {
                config.hide = true;
            });
            return;
        }
        openModalPropConfigs.forEach(config => {
            if (config.categoryId === 'openModal') {
                config.hide = propertyData.control.usageMode !== 'open-modal';
            }
            if (config.categoryId === 'openRemoteModal') {
                config.hide = propertyData.control.usageMode !== 'open-remote-modal';
            }
            if (config.categoryId === 'modalConfig') {
                config.hide = propertyData.control.usageMode === 'text';
            }
        });
    }

    private getUsualPropertyEntities(schemaField: any, fieldObject: any, viewModelId: string, fieldConfigs: any[]): PropertyEntity[] {

        const controlTypes = QuerySchemaFieldTypeEnums.getControlTypeEnum(schemaField.type.name);
        const controlType = fieldObject.control.controltype;
        const placeHolderProp = this.getPlaceHolder(controlType);
        const maxValuePropConfig = this.getMaxDatePropConfig(fieldObject, viewModelId);
        const minValuePropConfig = this.getMinDatePropConfig(fieldObject, viewModelId);
        const dateFieldList = this.getDateFieldInSchema(schemaField, viewModelId);

        const self = this;

        return [{
            propertyID: 'id',
            propertyName: '标识',
            propertyType: 'string',
            readonly: true
        }, {
            propertyID: 'code',
            propertyName: '编号',
            propertyType: 'string',
            readonly: true
        }, {
            propertyID: 'labelCode',
            propertyName: '标签',
            propertyType: 'string',
            readonly: true
        }, {
            propertyID: 'name',
            propertyName: '控件名称',
            propertyType: 'string'
        },
        ...placeHolderProp,
        {
            propertyID: 'control',
            propertyName: '控件',
            propertyType: 'cascade',
            isExpand: true,
            hideCascadeTitle: true,
            visible: true,
            cascadeConfig: [
                {
                    propertyID: 'controltype',
                    propertyName: '控件类型',
                    propertyType: 'select',
                    iterator: controlTypes
                }, {
                    propertyID: 'className',
                    propertyName: '样式',
                    propertyType: 'string'
                }, {
                    propertyID: 'require',
                    propertyName: '是否必填',
                    propertyType: 'boolean',
                    defaultValue: false
                },
                // {
                //     propertyID: 'helpId',
                //     propertyName: '帮助元数据',
                //     propertyType: 'modal',
                //     visible: controlType.includes('help'),
                //     category: ['help', 'combolist-help'],
                //     editor: SelectHelpMetadataComponent,
                //     editorParams: {
                //         viewModelId,
                //         bindingField: schemaField.bindingField,
                //         bindingType: 'Form',
                //         relativePath: this.formBasicService.formMetaBasicInfo.relativePath,
                //         boId: this.formBasicService.formMetaBasicInfo.bizobjectID,
                //     },
                //     converter: new SelectHelpConverter(),
                //     showClearButton: true
                // },
                {
                    propertyID: 'uri',
                    propertyName: 'uri',
                    propertyType: 'string',
                    visible: ['help', 'combolist-help', 'dropdown'].includes(controlType),
                    category: ['help', 'combolist-help', 'dropdown'],
                    readonly: ['help', 'combolist-help'].includes(controlType)
                },
                // {
                //     propertyID: 'textField',
                //     propertyName: '文本字段',
                //     propertyType: 'modal',
                //     visible: ['help', 'combolist-help'].includes(controlType),
                //     category: ['help', 'combolist-help'],
                //     editor: SelectHelpTextFieldComponent,
                //     editorParams: {
                //         helpId: fieldObject.control.helpId
                //     },
                //     beforeOpenModal(): BeforeOpenModalResult {
                //         if (!fieldObject.control.helpId) {
                //             return { result: false, message: '请先选择帮助元数据！' };
                //         }
                //         // 取帮助最新值
                //         this.editorParams.helpId = fieldObject.control.helpId;
                //         return { result: true, message: '' };

                //     }
                // },
                // {
                //     propertyID: 'valueField',
                //     propertyName: '值字段',
                //     propertyType: 'modal',
                //     visible: controlType.includes('help'),
                //     category: ['help', 'combolist-help'],
                //     editor: SelectHelpTextFieldComponent,
                //     editorParams: {
                //         helpId: fieldObject.control.helpId
                //     },
                //     beforeOpenModal(): BeforeOpenModalResult {
                //         if (!fieldObject.control.helpId) {
                //             return { result: false, message: '请先选择帮助元数据！' };
                //         }
                //         // 取帮助最新值
                //         this.editorParams.helpId = fieldObject.control.helpId;
                //         return { result: true, message: '' };

                //     }
                // },
                {
                    propertyID: 'idField',
                    propertyName: '标识字段',
                    propertyType: 'string',
                    visible: ['help', 'combolist-help'].includes(controlType),
                    category: ['help', 'combolist-help'],
                    readonly: true
                }, {
                    propertyID: 'displayType',
                    propertyName: '显示类型',
                    propertyType: 'string',
                    visible: controlType.includes('help'),
                    category: ['help', 'combolist-help'],
                    readonly: true
                }, {
                    propertyID: 'mapFields',
                    propertyName: '映射',
                    propertyType: 'modal',
                    editor: SelectMappingComponent,
                    editorParams: {
                        viewModelId,
                        sourceMetadataId: fieldObject.control.helpId,
                        binding: {
                            type: 'Form',
                            field: fieldObject.id
                        }
                    },
                    converter: new MappingConverter(),
                    visible: controlType.includes('help'),
                    category: ['help', 'combolist-help']
                }, {
                    propertyID: 'enableExtendLoadMethod',
                    propertyName: '是否启用扩展取数',
                    propertyType: 'boolean',
                    visible: fieldObject.control.helpId && controlType.includes('help'),
                    category: ['help', 'combolist-help'],
                    defaultValue: false
                },
                {
                    propertyID: 'enableFullTree',
                    propertyName: '构造完整树',
                    propertyType: 'boolean',
                    defaultValue: false,
                    category: ['help', 'combolist-help'],
                    visible: controlType.includes('help') && fieldObject.control.displayType &&
                        (fieldObject.control.displayType.toLowerCase() === 'treelist' || fieldObject.control.displayType.toLowerCase() === 'navtreelist')
                },
                {
                    propertyID: 'loadTreeDataType',
                    propertyName: '数据加载方式',
                    propertyType: 'select',
                    defaultValue: 'default',
                    iterator:
                        [{ key: 'default', value: '默认' }, { key: 'loadall', value: '全部加载' }, { key: 'layerload', value: '分层加载' }],
                    visible: controlType.includes('help') && fieldObject.control.displayType && fieldObject.control.displayType.toLowerCase() === 'treelist',
                    category: ['help', 'combolist-help']
                },
                {
                    propertyID: 'multiSelect',
                    propertyName: '是否多选',
                    propertyType: 'boolean',
                    defaultValue: false,
                    category: ['help', 'combolist-help', 'dropdown'],
                    visible: ['help', 'combolist-help', 'dropdown'].includes(controlType)
                },
                {
                    propertyID: 'enableCascade',
                    propertyName: '启用级联选择',
                    propertyType: 'boolean',
                    defaultValue: false,
                    category: ['help', 'combolist-help'],
                    visible: controlType === 'help' && fieldObject.control.multiSelect
                        && fieldObject.control.displayType &&
                        (fieldObject.control.displayType.toLowerCase() === 'treelist' ||
                            fieldObject.control.displayType.toLowerCase() === 'navtreelist')
                },
                {
                    propertyID: 'cascadeStatus',
                    propertyName: '级联状态',
                    propertyType: 'select',
                    description: '级联状态选择',
                    defaultValue: 'enable',
                    iterator: [
                        { key: 'enable', value: '启用级联' },
                        { key: 'up', value: '仅向上级联' },
                        { key: 'down', value: '仅向下级联' },
                        { key: 'disable', value: '禁用级联' }],
                    visible: controlType === 'help' && fieldObject.control.multiSelect
                        && fieldObject.control.displayType &&
                        (fieldObject.control.displayType.toLowerCase() === 'treelist' ||
                            fieldObject.control.displayType.toLowerCase() === 'navtreelist') &&
                        fieldObject.control.enableCascade,
                },
                {
                    propertyID: 'expandLevel',
                    propertyName: '默认展开层级',
                    propertyType: 'number',
                    decimals: 0,
                    min: -1,
                    defaultValue: -1,
                    category: ['help', 'combolist-help'],
                    visible: controlType.includes('help') && fieldObject.control.displayType &&
                        (fieldObject.control.displayType.toLowerCase() === 'treelist' || fieldObject.control.displayType.toLowerCase() === 'navtreelist')
                },
                {
                    propertyID: 'editable',
                    propertyName: '是否允许输入',
                    propertyType: 'boolean',
                    category: ['help', 'input-group'],
                    visible: controlType === 'input-group' || controlType === 'help'
                },
                {
                    propertyID: 'nosearch',
                    propertyName: '任意输入',
                    propertyType: 'boolean',
                    defaultValue: false,
                    category: ['help'],
                    visible: controlType === 'help'
                },
                // {
                //     propertyID: 'displayFields',
                //     propertyName: '展示字段',
                //     propertyType: 'modal',
                //     category: ['help'],
                //     visible: controlType === 'help',
                //     editor: SelectHelpDisplayFieldsComponent,
                //     editorParams: {
                //         helpId: fieldObject.control.helpId
                //     },
                //     beforeOpenModal(): BeforeOpenModalResult {
                //         if (!fieldObject.control.helpId) {
                //             return { result: false, message: '请先选择帮助元数据！' };
                //         }
                //         // 取帮助最新值
                //         this.editorParams.helpId = fieldObject.control.helpId;
                //         return { result: true, message: '' };

                //     }
                // },
                {
                    propertyID: 'clearFields',
                    propertyName: '值变化时清空字段',
                    propertyType: 'modal',
                    category: ['help'],
                    visible: controlType === 'help',
                    editor: SelectHelpClearFieldsEditorComponent,
                    editorParams: {
                        fieldConfigs,
                        currentId: fieldObject.id
                    },
                    showClearButton: true,
                    beforeOpenModal(): BeforeOpenModalResult {
                        // 取配置字段的最新值
                        this.editorParams.fieldConfigs = self.fieldConfigs;
                        return { result: true, message: '' };

                    }
                },
                {
                    propertyID: 'pageList',
                    propertyName: '分页条数',
                    propertyType: 'string',
                    description: '请输入以英文逗号分开的数字，最大值为1000。例如：10,20,30,50,100',
                    category: ['help'],
                    visible: controlType === 'help' && fieldObject.control.displayType && fieldObject.control.displayType.toLowerCase() !== 'treelist',
                    notAllowedChars: [/[^\d,]/g]
                },
                {
                    propertyID: 'pageSize',
                    propertyName: '默认分页条数',
                    propertyType: 'select',
                    iterator: this.getPageSizeIterator(fieldObject.control.pageList),
                    category: ['help'],
                    visible: controlType === 'help' && fieldObject.control.displayType && fieldObject.control.displayType.toLowerCase() !== 'treelist'
                },
                {
                    propertyID: 'valueType',
                    propertyName: '值类型',
                    propertyType: 'select',
                    visible: controlType === 'dropdown',
                    category: ['dropdown'],
                    iterator: [{ key: '1', value: '字符串' }, { key: '0', value: '整型' }, { key: '2', value: '布尔' }]
                },
                {
                    propertyID: 'enumValues',
                    propertyName: '枚举数组',
                    propertyType: 'modal',
                    visible: controlType === 'dropdown',
                    category: ['dropdown'],
                    editor: ItemCollectionEditorComponent,
                    converter: new ItemCollectionConverter(),
                    ...this.enumDataConfig.editorConfig,
                },
                {
                    propertyID: 'startFieldCode',
                    propertyName: '开始日期字段',
                    propertyType: 'select',
                    category: ['date'],
                    visible: ['date'].includes(controlType) && [FormSchemaEntityFieldTypeName.Date, FormSchemaEntityFieldTypeName.DateTime].includes(schemaField.type.name),
                    iterator: dateFieldList
                },
                {
                    propertyID: 'endFieldCode',
                    propertyName: '结束日期字段',
                    propertyType: 'select',
                    category: ['date'],
                    visible: ['date'].includes(controlType) && [FormSchemaEntityFieldTypeName.Date, FormSchemaEntityFieldTypeName.DateTime].includes(schemaField.type.name),
                    iterator: dateFieldList
                },
                ...this.getFormatProps(fieldObject, schemaField),
                {
                    propertyID: 'weekSelect',
                    propertyName: '是否启用周选择',
                    propertyType: 'boolean',
                    category: ['date'],
                    visible: controlType === 'date'
                },
                {
                    propertyID: 'precision',
                    propertyName: '精度',
                    propertyType: 'number',
                    decimals: 0,
                    min: 0,
                    visible: controlType === 'number' || controlType === 'single-number',
                    category: ['number', 'single-number']
                },
                {
                    propertyID: 'dialogTitle',
                    propertyName: '帮助标题',
                    propertyType: 'string',
                    visible: controlType === 'help'
                },
                {
                    propertyID: 'panelWidth',
                    propertyName: '面板宽度',
                    propertyType: 'number',
                    decimals: 0,
                    min: 0,
                    visible: controlType === 'combolist-help' || controlType === 'help',
                    category: ['combolist-help', 'help']
                },
                {
                    propertyID: 'panelHeight',
                    propertyName: '面板高度',
                    propertyType: 'number',
                    decimals: 0,
                    min: 0,
                    visible: controlType === 'dropdown' || controlType === 'combolist-help' || controlType === 'help',
                    category: ['dropdown', 'combolist-help', 'help']
                },
                {
                    propertyID: 'textAlign',
                    propertyName: '数据水平对齐方式',
                    propertyType: 'select',
                    iterator: [
                        { key: 'left', value: '靠左' },
                        { key: 'center', value: '居中' },
                        { key: 'right', value: '靠右' }
                    ],
                    visible: controlType === 'number' || controlType === 'single-number',
                    category: ['number', 'single-number']
                },
                maxValuePropConfig,
                minValuePropConfig,
                {
                    propertyID: 'horizontal',
                    propertyName: '是否水平布局',
                    propertyType: 'boolean',
                    category: ['radio'],
                    visible: controlType === 'radio'
                },
                {
                    propertyID: 'showLabel',
                    propertyName: '是否显示标签',
                    propertyType: 'boolean',
                    defaultValue: false,
                    category: ['radio'],
                    visible: controlType === 'radio'
                },
                {
                    propertyID: 'groupText',
                    propertyName: '按钮显示文本',
                    propertyType: 'modal',
                    editor: CodeEditorComponent,
                    editorParams: {
                        language: 'html'
                    },
                    category: ['input-group'],
                    visible: controlType === 'input-group'
                },
                // {
                //     propertyID: 'textAlign',
                //     propertyName: '数据水平对齐方式',
                //     propertyType: 'select',
                //     iterator: [{ key: 'left', value: '靠左' }, { key: 'right', value: '靠右' }, { key: 'center', value: '居中' }]
                // },
                {
                    propertyID: 'usageMode',
                    propertyName: '使用模式',
                    propertyType: 'select',
                    iterator: [
                        { key: 'text', value: '文本' },
                        { key: 'open-modal', value: '弹出表单' },
                        { key: 'open-remote-modal', value: '弹出远端表单' }
                    ],
                    refreshPanelAfterChanged: true,
                    category: ['input-group'],
                    visible: controlType === 'input-group'
                },
                {
                    propertyID: 'isDynamicDate',
                    propertyName: '是否支持动态日期',
                    propertyType: 'boolean',
                    defaultValue: false,
                    category: ['single-date'],
                    visible: controlType === 'single-date'
                }
            ]
        }];
    }

    private getDateFieldInSchema(schemaField: FormSchemaEntityField, viewModelId: string) {
        const dateFieldTypes = [FormSchemaEntityFieldTypeName.Date, FormSchemaEntityFieldTypeName.DateTime];
        if (!dateFieldTypes.includes(schemaField.type.name)) {
            return [];
        }
        const schemaFields: FormSchemaEntityField[] = this.schemaService.getFieldsByViewModelId(viewModelId);
        // const dgVM = this.dgVMService.getDgViewModel(viewModelId);
        const dateFields = schemaFields.filter(field => dateFieldTypes.includes(field.type.name));

        const iterators = [];
        dateFields.forEach(element => {
            iterators.push({
                key: element.code,
                value: element.name
            });
        });
        return iterators;
    }
    /**
     * 帮助控件快捷选择属性
     */
    private getHelpQuickSelectPropConfig(propertyData: any, viewModelId: string): ElementPropertyConfig {
        // const self = this;
        const control = propertyData.control;
        // 适配旧表单没有quickSelect节点
        if (control.controltype === 'help' && !control.quickSelect) {
            propertyData.control.quickSelect = {
                enable: false,
                showItemsCount: 10,
                formatter: null,
                showMore: true
            };
        }

        let showQuickSelect = false;
        // 规则：单列表或左树右列表类型的弹出帮助
        if (control.controltype === 'help' && ['list', 'navtreelist', 'navlist'].includes(control.displayType.toLowerCase())) {
            // 若启用多选，只支持标签类型的帮助
            if (control.multiSelect) {
                showQuickSelect = control.viewType === 'tag';
            } else {
                // 不启用多选
                showQuickSelect = true;
            }
        }

        return {
            categoryId: 'helpQuickSelect',
            categoryName: '快捷配置',
            hide: !showQuickSelect,
            propertyData: control.quickSelect,
            enableCascade: true,
            parentPropertyID: 'control.quickSelect',
            properties: [
                {
                    propertyID: 'enable',
                    propertyName: '启用快捷选择',
                    propertyType: 'boolean',
                    defaultValue: false
                },
                {
                    propertyID: 'showItemsCount',
                    propertyName: '展示数据条数',
                    propertyType: 'number',
                    visible: control.quickSelect && control.quickSelect.enable,
                    min: 5,
                    max: 10,
                    decimals: 0
                },
                {
                    propertyID: 'formatter',
                    propertyName: '格式化',
                    propertyType: 'modal',
                    visible: control.quickSelect && control.quickSelect.enable,
                    editor: CodeEditorComponent,
                    editorParams: {
                        language: 'javascript',
                        exampleCode: "(data) => {\r\n    return `${data['name']} - <b>${data['birthday']}</b>`\r\n}\r\n\r\n注： data 帮助中的每行数据"
                    }
                },
                {
                    propertyID: 'showMore',
                    propertyName: '显示更多按钮',
                    propertyType: 'boolean',
                    description: '是否显示更多按钮',
                    visible: control.quickSelect && control.quickSelect.enable
                }

            ],
            setPropertyRelates(changeObject, propData, parameters) {
                if (!changeObject) {
                    return;
                }
                switch (changeObject.propertyID) {
                    case 'enable': {
                        this.properties.map(p => {
                            if (p.propertyID !== 'enable') {
                                p.visible = changeObject.propertyValue;
                            }
                        });
                        break;
                    }
                }
            }
        };
    }
    private getOpenModalPropConfigs(propertyData: any, viewModelId: string): ElementPropertyConfig[] {
        const self = this;
        const control = propertyData.control;
        if (!control.modalConfig) {
            propertyData.control.modalConfig = {
                modalCmp: null,
                mapFields: null,
                showHeader: true,
                title: '',
                showCloseButton: true,
                showMaxButton: true,
                width: 800,
                height: 600,
                showFooterButtons: true,
                footerButtons: []
            };
        }
        return [{
            categoryId: 'openModal',
            categoryName: '表单配置',
            hide: control.usageMode !== 'open-modal',
            propertyData: control.modalConfig,
            enableCascade: true,
            parentPropertyID: 'control.modalConfig',
            properties: [
                {
                    propertyID: 'modalCmp',
                    propertyName: '弹出表单',
                    propertyType: 'modal',
                    editor: ImportCmpComponent,
                    converter: new ImportCmpConverter(),
                    editorParams: { containerType: DgControl.ModalContainer.type, containerId: propertyData.id, relativePath: this.formBasicService.formMetaBasicInfo.relativePath, name: this.formBasicService.formMetaBasicInfo.name },
                    showClearButton: true,
                    afterClickClearButton(oldValue: string) {
                        self.domService.deleteExternalComponent(oldValue); // 清空外部组件的声明节点
                    }
                },
                {
                    propertyID: 'mapFields',
                    propertyName: '字段映射',
                    propertyType: 'modal',
                    editor: SelectMappingComponent,
                    editorParams: {
                        sourceMetadataId: control.modalConfig.formId,
                        viewModelId,
                        binding: {
                            type: 'Form'
                        },
                        sourceMetadataType: 'form',
                        sourceMetadataName: '弹出表单'
                    },
                    converter: new MappingConverter(),
                    beforeOpenModal(): BeforeOpenModalResult {
                        if (!control.modalConfig || !control.modalConfig.formId) {
                            return { result: false, message: '请先选择弹出表单！' };
                        }
                        // 取弹出表单和绑定的最新值
                        this.editorParams.sourceMetadataId = control.modalConfig.formId;
                        return { result: true, message: '' };
                    }
                }

            ],
            setPropertyRelates(changeObject, propData, parameters) {
                if (!changeObject) {
                    return;
                }
                switch (changeObject.propertyID) {
                    case 'modalCmp': {
                        propData.component = parameters ? parameters.component : '';
                        propData.formId = parameters ? parameters.uri : '';
                        propData.mapFields = '';
                        break;
                    }
                }
                Object.assign(propertyData.control.modalConfig, propData);
            }
        },
        {
            categoryId: 'openRemoteModal',
            categoryName: '表单配置',
            hide: control.usageMode !== 'open-remote-modal',
            propertyData: control.modalConfig,
            enableCascade: true,
            parentPropertyID: 'control.modalConfig',
            properties: [
                {
                    propertyID: 'mapFields',
                    propertyName: '字段映射',
                    propertyType: 'modal',
                    editor: InputgroupFormMappingEditorComponent,
                    converter: new MappingConverter(),
                }

            ],
            setPropertyRelates(changeObject, propData, parameters) {
                if (!changeObject) {
                    return;
                }
                Object.assign(propertyData.control.modalConfig, propData);
            }
        },
        {
            categoryId: 'modalConfig',
            categoryName: '弹出窗口配置',
            hide: control.controltype !== 'input-group' || control.usageMode === 'text',
            propertyData: control.modalConfig,
            enableCascade: true,
            parentPropertyID: 'control.modalConfig',
            properties: [
                {
                    propertyID: 'showHeader',
                    propertyName: '显示标题栏',
                    propertyType: 'boolean'
                },
                {
                    propertyID: 'title',
                    propertyName: '标题',
                    propertyType: 'string',
                    visible: control.modalConfig && control.modalConfig.showHeader,
                    category: 'header'
                },
                {
                    propertyID: 'showCloseButton',
                    propertyName: '显示关闭按钮',
                    propertyType: 'boolean',
                    visible: control.modalConfig && control.modalConfig.showHeader,
                    category: 'header'
                },
                {
                    propertyID: 'showMaxButton',
                    propertyName: '显示最大化按钮',
                    propertyType: 'boolean',
                    visible: control.modalConfig && control.modalConfig.showHeader,
                    category: 'header'
                },
                {
                    propertyID: 'width',
                    propertyName: '宽度',
                    propertyType: 'number',
                    min: 0
                },
                {
                    propertyID: 'height',
                    propertyName: '高度',
                    propertyType: 'number',
                    min: 0
                }
                // {
                //     propertyID: 'showFooterButtons',
                //     propertyName: '显示底部按钮区',
                //     propertyType: 'boolean'
                // },
                // {
                //     propertyID: 'footerButtons',
                //     propertyName: '按钮组',
                //     propertyType: 'modal',
                //     editor: ToolbarEditorComponent,
                //     editorParams: { viewModelId, disableChildItem: true, defaultBtnClass: 'btn' },
                //     converter: new ToolBarConverter(),
                //     visible: control.modalConfig && control.modalConfig.showFooterButtons
                // }

            ],
            setPropertyRelates(changeObject, propData, parameters) {
                if (!changeObject) {
                    return;
                }
                switch (changeObject.propertyID) {
                    case 'showHeader': {
                        this.properties.map(p => {
                            if (p.category === 'header') {
                                p.visible = changeObject.propertyValue;
                            }
                        });

                        break;
                    }
                    case 'showFooterButtons': {
                        const footerButtons = this.properties.find(p => p.propertyID === 'footerButtons');
                        if (footerButtons) {
                            footerButtons.visible = changeObject.propertyValue;
                        }
                    }
                }

                Object.assign(propertyData.control.modalConfig, propData);
            }
        }];
    }

    private getPageSizeIterator(pageList: string) {
        if (!pageList) {
            // pageList = '10,20,30,50,100';
            return [];
        }
        const iterator = [];
        pageList.split(',').forEach(pageSize => {
            iterator.push({
                key: Number.parseInt(pageSize, 10),
                value: pageSize
            });
        });
        return iterator;
    }

    /**
     * 控制输入的分页最大值为1000
     */
    private checkPageList(pageList: string) {
        if (!pageList) {
            return '';
        }
        let iterator = pageList.split(',');
        iterator = iterator.filter(i => Number.parseInt(i, 10) <= 1000);
        return iterator.join(',');
    }

    private getMaxDatePropConfig(fieldObject: any, viewModelId: string) {
        const controlType = fieldObject.control.controltype;
        let visible = false;
        switch (fieldObject.control.controltype) {
            case 'number': case 'single-number': {
                visible = (controlType === 'number' || controlType === 'single-number') && !fieldObject.control.isBigNumber;
                break;
            }
            // case 'single-year': {
            //     visible = true;
            //     break;
            // }
        }
        return {
            propertyID: 'maxValue',
            propertyName: '最大值',
            propertyType: 'number',
            visible,
            category: ['number', 'single-number'],
            min: fieldObject.control.minValue ? fieldObject.control.minValue : undefined,
            decimals: fieldObject.control.precision,
            // editor: BindingCustomEditorComponent,
            // editorParams: {
            //     modalTitle: '最大值编辑器',
            //     viewModelId,
            //     allowedBindingType: 'LocaleVariable,RemoteVariable'
            // },
            // converter: new BindingCustomEditorConverter()
        };

    }

    private getMinDatePropConfig(fieldObject: any, viewModelId: string) {
        const controlType = fieldObject.control.controltype;
        let visible = false;
        switch (fieldObject.control.controltype) {
            case 'number': case 'single-number': {
                visible = (controlType === 'number' || controlType === 'single-number') && !fieldObject.control.isBigNumber;
                break;
            }
        }
        return {
            propertyID: 'minValue',
            propertyName: '最小值',
            propertyType: 'number',
            visible,
            category: ['number', 'single-number'],
            max: fieldObject.control.maxValue ? fieldObject.control.maxValue : undefined,
            decimals: fieldObject.control.precision
        };

    }

    private getFormatProps(propertyData: any, schemaField: FormSchemaEntityField): PropertyEntity[] {

        const controlData = propertyData.control;
        const controlType = controlData.controltype;

        const isStringField = schemaField.type.name === FormSchemaEntityFieldTypeName.String;
        const supportFormatControlType = ['date', 'single-date', 'date-time', 'single-date-time', 'single-year', 'single-month', 'month'];

        const returnFormat = isStringField ? controlData.returnFormat : null;
        return [
            {
                propertyID: 'returnFormat',
                propertyName: '查询格式',
                propertyType: 'select',
                iterator: this.getDateReturnFormatIteratror(controlType, controlData.enableCustomFormat),
                visible: isStringField && supportFormatControlType.includes(controlType),
                description: '数据在服务器端sql查询时所用的格式',
            },
            {
                propertyID: 'enableCustomFormat',
                propertyName: '启用自定义显示格式',
                propertyType: 'boolean',
                visible: ['date-time', 'single-date-time'].includes(controlType),
                description: '若不启用自定义格式，将自动为显示格式追加时分秒',
                readonly: controlData.returnFormat && !controlData.returnFormat.includes('HH')
            },
            {
                propertyID: 'format',
                propertyName: '显示格式',
                propertyType: 'select',
                iterator: this.getDateFormatIteratror(controlType, controlData.enableCustomFormat, returnFormat),
                visible: supportFormatControlType.includes(controlType),
                description: '显示在界面上的格式',
            }
        ];




    }

    /**
     * 日期存储格式化枚举项
     */
    private getDateReturnFormatIteratror(controlType: string, enableCustomFormat = false): KeyMap[] {
        const returnFormats = [];
        const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS;

        switch (controlType) {
            // 日期区间、单日期
            case 'date': case 'single-date': {
                returnFormats.push(...yMdFormats, ...yMFormats, ...yFormats, ...mdFormats);
                break;
            }
            // 日期时间区间、单日期时间
            case 'date-time': case 'single-date-time': {
                if (enableCustomFormat) {
                    returnFormats.push(...timeFormats, ...yMdFormats, ...yMFormats, ...yFormats, ...mdFormats);
                } else {
                    returnFormats.push(...timeFormats);
                }
                break;
            }
            // 单年度
            case 'single-year': {
                returnFormats.push(...yFormats);
                break;
            }
            // 单月份、月份区间
            case 'single-month': case 'month': {
                returnFormats.push(...yMFormats);
                break;
            }
        }

        return returnFormats;
    }

    /**
     * 日期显示格式化枚举项
     */
    private getDateFormatIteratror(controlType: string, enableCustomFormat = false, returnFormat?: string): KeyMap[] {
        let formats = [];

        const { timeFormats, yMdFormats, yMFormats, mdFormats, yFormats } = DATE_FORMATS;

        switch (controlType) {
            // 日期区间、单日期
            case 'date': case 'single-date': {
                formats.push(...yMdFormats, ...yMFormats, ...yFormats, ...mdFormats);
                break;
            }
            // 日期时间区间、单日期时间
            case 'date-time': case 'single-date-time': {
                if (enableCustomFormat) {
                    formats.push(...timeFormats, ...yMdFormats, ...yMFormats, ...yFormats, ...mdFormats);
                } else {
                    formats.push(...yMdFormats);
                }
                break;
            }
            // 单年度
            case 'single-year': {
                formats.push(...yFormats);
                break;
            }
            // 单月份、月份区间
            case 'single-month': case 'month': {
                formats.push(...yMFormats);
                break;
            }
        }
        formats = this.filterFormatNotInReturnFormat(formats, returnFormat);
        return formats;
    }





    /**
     * 根据选择的存储格式过滤显示格式。
     * 例如存储格式为yyyy年MM月，那么显示格式就不能配置yyyy年MM月dd日
     * @param formatIterator 显示格式枚举项
     * @param selectedReturnFormat  存储格式
     */
    filterFormatNotInReturnFormat(formatIterator: KeyMap[], selectedReturnFormat: string) {
        if (!selectedReturnFormat) {
            return formatIterator;
        }
        const hasReturnYFormat = selectedReturnFormat.includes('yyyy');
        const hasReturnMFormat = selectedReturnFormat.includes('MM');
        const hasReturndFormat = selectedReturnFormat.includes('dd');
        const hasReturnHFormat = selectedReturnFormat.includes('HH');
        const hasReturnmFormat = selectedReturnFormat.includes('mm');
        const hasReturnsFormat = selectedReturnFormat.includes('ss');


        if (!hasReturnYFormat) {
            formatIterator = formatIterator.filter(format => !format.key.includes('yyyy'));
        }
        if (!hasReturnMFormat) {
            formatIterator = formatIterator.filter(format => !format.key.includes('MM'));
        }
        if (!hasReturndFormat) {
            formatIterator = formatIterator.filter(format => !format.key.includes('dd'));
        }
        if (!hasReturnHFormat) {
            formatIterator = formatIterator.filter(format => !format.key.includes('HH'));
        }
        if (!hasReturnmFormat) {
            formatIterator = formatIterator.filter(format => !format.key.includes('mm'));
        }
        if (!hasReturnsFormat) {
            formatIterator = formatIterator.filter(format => !format.key.includes('ss'));
        }

        return formatIterator;
    }
    /**
     * 枚举数据的编辑器不同：
     * kendo的控件确定只有value-name键值
     * farris的控件若绑定了枚举字段只有value-name 键值；若绑定了变量或者字符串字段则可以自行指定idField 和textField
     */
    private getEnumDataConfig(propertyData: any, schemaField: any): { editorConfig: any, dynamicMappingKeys: boolean } {

        const editorConfig: any = {
            editorParams: {
                columns: [
                    { field: 'value', title: '枚举值', editor: { type: schemaField.type.name === 'Boolean' ? EditorTypes.CHECKBOX : EditorTypes.TEXTBOX } },
                    { field: 'name', title: '枚举名称', editor: { type: EditorTypes.TEXTBOX } },
                ],
                requiredFields: ['value', 'name'],
                uniqueFields: ['value', 'name'],
                modalTitle: '枚举编辑器',
                canEmpty: true
            }
        };

        // 绑定枚举字段的 下拉控件，编辑器只支持value-name
        if (schemaField.type.name === 'Enum') {
            return { editorConfig, dynamicMappingKeys: false };
        }

        editorConfig.editorParams.dynamicMappingKeys = true;
        editorConfig.editorParams.valueField = propertyData.idField;
        editorConfig.editorParams.nameField = propertyData.textField;

        return { editorConfig, dynamicMappingKeys: true };
    }
}

